//
//  The MIT License (MIT)
//
//  Copyright (c) 2017 Snips
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in all
//  copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//  SOFTWARE.
//

import Foundation
import libetpan

public typealias ContentDispositionAttribute = (name: String, value: String)

public enum ContentDisposition {
    case inline([ContentDispositionAttribute])
    case attachment([ContentDispositionAttribute])
}

// MARK: IMAP Parsing

extension mailimap_body_fld_dsp {
    var parse: ContentDisposition? {
        guard let list = dsp_attributes?.pointee.pa_list else { return nil }

        let attributes = sequence(list, of: mailimap_single_body_fld_param.self).compactMap { $0.parse }
        
        switch String.fromUTF8CString(dsp_type)?.lowercased() {
        case .some("inline"): return .inline(attributes)
        case .some("attachment"): return .attachment(attributes)
        default: return nil
        }
    }
}

extension mailimap_single_body_fld_param {
    var parse: ContentDispositionAttribute? {
        guard let name = String.fromUTF8CString(pa_name)?.lowercased() else { return nil }
        let value = String.fromZeroSizedCStringMimeHeader(pa_value) ?? ""
        return (name: name, value: value)
    }
}

// MARK: IMF Parsing

extension mailmime_disposition_type {
    var parse: ContentDisposition? {
        switch Int(dsp_type) {
        case MAILMIME_DISPOSITION_TYPE_INLINE: return .inline([])
        case MAILMIME_DISPOSITION_TYPE_ATTACHMENT: return .attachment([])
        default: return nil
        }
    }
}
